package onpu_dms_xls.kernel.common.XML_Parsers;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import onpu_dms_xls.exceptions.MyException;
import onpu_dms_xls.kernel.common.Util;
import onpu_dms_xls.kernel.common.VariableDeclaration;
import onpu_dms_xls.kernel.common.VariableType;
import onpu_dms_xls.kernel.common.VariableType_DBRelationTypes;
import onpu_dms_xls.kernel.common.VariableType_InputRelationTypes;
import onpu_dms_xls.kernel.common.VariableType_XLSVisibilityTypes;
import onpu_dms_xls.kernel.common.logAndDebug.Debug;
import onpu_dms_xls.kernel.common.logAndDebug.LoggingFacade;
import org.apache.log4j.Logger;


public class SAX_XML_Template_Parser extends DefaultHandler {
    

    private List<VariableDeclaration> varDeclArr;
    private String tempVal;
    //to maintain context
    private VariableDeclaration tempVarDecl;
    private boolean inIterationRow = false;
    private String iterationRowSingleFromDBQuery;

    public SAX_XML_Template_Parser() {
        varDeclArr = new ArrayList<VariableDeclaration>();
    }

    public VariableDeclaration[] runExample(String xmlFilePath) {
        parseDocument(xmlFilePath);

        return (VariableDeclaration[]) varDeclArr.toArray(new VariableDeclaration[]{});
    }

    private void parseDocument(String xmlFilePath) {

        //get a factory
        SAXParserFactory spf = SAXParserFactory.newInstance();
        try {
            //get a new instance of parser
            SAXParser sp = spf.newSAXParser();

            //parse the file and also register this class for call backs
            sp.parse(xmlFilePath, this);

        } catch (SAXException se) {
            se.printStackTrace();
        } catch (ParserConfigurationException pce) {
            pce.printStackTrace();
        } catch (IOException ie) {
            ie.printStackTrace();
        }
    }

    //Event Handlers
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        //reset
        tempVal = "";
        LoggingFacade.trace.trace("qName: "+qName);

        if (qName.equalsIgnoreCase("iterationrow")) {
            inIterationRow = true;
            this.iterationRowSingleFromDBQuery = attributes.getValue("singleFromDBQuery");
        } else if (qName.equalsIgnoreCase("varDecl")) {
            //create a new instance of variable declaration
            tempVarDecl = new VariableDeclaration();
            tempVarDecl.setDataType(Util.stringToDataType(attributes.getValue("type")));
            tempVarDecl.setDefaultValue(attributes.getValue("defaultValue"));
            VariableType vt = new VariableType();
            try {
                vt.setDB_Relation(VariableType_DBRelationTypes.getTypeFromName(attributes.getValue("varType_DBRelation")));
                vt.setInput_Relation(VariableType_InputRelationTypes.getTypeFromName(attributes.getValue("varType_InputRelation")));
                if (attributes.getValue("varType_XLSVisisbility") != null){
                    vt.setXLS_Visibility(VariableType_XLSVisibilityTypes.getTypeFromName(attributes.getValue("varType_XLSVisisbility")));
                } else if (attributes.getValue("varType_Visibility") != null){
                    vt.setXLS_Visibility(VariableType_XLSVisibilityTypes.getTypeFromName(attributes.getValue("varType_Visibility")));
                }
            } catch (MyException e) {
                throw new SAXException (e.toString());
            }
           
            tempVarDecl.setVarType(vt);

            if (vt.getDB_Relation().equals(VariableType_DBRelationTypes.SELECT)) {
                tempVarDecl.setFromDBQuery(attributes.getValue("fromDBQuery"));
            } else if (vt.getDB_Relation().equals(VariableType_DBRelationTypes.UPDATE)) {
                tempVarDecl.setFromDBQuery(attributes.getValue("fromDBQuery"));
                tempVarDecl.setToDBQuery(attributes.getValue("toDBQuery"));
            }

            if (inIterationRow) {
                tempVarDecl.setIsInIteration(true);
                tempVarDecl.setIterationRowSingleFromDBQuery(iterationRowSingleFromDBQuery);
            }
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        tempVal = new String(ch, start, length);
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {



        if (qName.equalsIgnoreCase("varDecl")) {
            //add it to the list
            tempVarDecl.setVarName(tempVal);
            varDeclArr.add(tempVarDecl);

        } else if (qName.equalsIgnoreCase("iterationrow")) {
            inIterationRow = false;
        }

    }
}




